package controllers.admin;

import java.util.List;

import models.admin.PagePermission;
import models.admin.Permission;
import models.admin.Role;

import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.AuditQuery;
import org.hibernate.envers.query.criteria.AuditDisjunction;

import play.db.jpa.JPA;
import play.mvc.With;
import controllers.BaseController;
import controllers.Check;
import controllers.Secure;

/**
 * @author rjanixz
 *
 */
@With(Secure.class)
public class Roles extends BaseController {

	@Check(value = "EDIT")
	public static void edit(Long id) {
		List<PagePermission> pagePermissions = PagePermission.findAll();
		Role role = Role.findById(id);
		render(role, pagePermissions);
	}
	
	@Check(value = "ADD")
	public static void save(String name, String description) {
		Role role = new Role();
		role.setName(name);
		role.setDescription(description);
		role.save();
		redirect("/admin/roles/all");
	}

	@Check(value = "EDIT")
	public static void update(Long roleId, String name, String description) {
		Role role = Role.findById(roleId);
		role.setDescription(description);
		role.setName(name);
		role.save();
		redirect("/admin/roles/all");
	}
	
	@Check(value = "EDIT")
	public static void addDetail(Long roleId, Long pagePermissionId) {
		PagePermission pagePermission = PagePermission.findById(pagePermissionId);
		Role role = Role.findById(roleId);
		role.getPagePermissions().add(pagePermission);
		role.save();
		redirect("/admin/roles/edit/"+roleId);
	}
	
	@Check(value = "EDIT")
	public static void removeDetail(Long roleId, Long pagePermissionId) {
		Role role = Role.findById(roleId);
		PagePermission pagePermission = PagePermission.findById(pagePermissionId);
		role.getPagePermissions().remove(pagePermission);
		role.save();
		redirect("/admin/roles/edit/"+roleId);
	}

	@Check(value = "AUDIT")
	public static void audit(Long id) {

		AuditReader reader = AuditReaderFactory.get(JPA.em());

		List<Number> revisions = reader.getRevisions(Role.class, id);

		List<Object[]> roles = reader
				.createQuery()
				.forRevisionsOfEntity(Role.class, Role.class.getName(), false,
						true).add(AuditEntity.revisionNumber().in(revisions))
				.getResultList();

		render(roles);
	}

	@Check(value = "AUDIT")
	public static void auditViewDeleted() {
		  
		AuditReader reader = AuditReaderFactory.get(JPA.em());

		List<Role> deletedRoles = reader.createQuery()
				.forRevisionsOfEntity(Role.class, true, true)
				.add(AuditEntity.revisionType().eq(RevisionType.DEL))
				.getResultList();

		AuditQuery query = reader.createQuery().forRevisionsOfEntity(
				Role.class, Role.class.getName(), false, true);

		AuditDisjunction conjuntion = new AuditDisjunction();
		for (Role role : deletedRoles) {
			conjuntion.add(AuditEntity.id().eq(role.id));
		}
		query.add(conjuntion);

		// getting deleted ids
		List<Object[]> roles = query.getResultList();

		renderTemplate("/admin/roles/audit.html", roles);
	}
}
